//
//  LBMediaRotateScroller.m
//  LBCropImagePage
//
//  Created by mac on 2024/5/26.
//

#import "LBMediaRotateScroller.h"

@interface LBMediaRotateScroller () <UIScrollViewDelegate>

@property (nonatomic, strong) UIScrollView *scroller;
@property (nonatomic, strong) UILabel *label;
@property (nonatomic, strong) UIView *indicator;
@property (nonatomic, copy) NSArray <UIView *> *keyDegreeBar;
@property (nonatomic, assign) BOOL isFeedback;

@end

@implementation LBMediaRotateScroller

- (instancetype)initWithAngle:(CGFloat)angle
{
    if (self = [super init]) {
        [self updateWithAngle:angle];
    }
    return self;
}

- (void)updateWithAngle:(CGFloat)angle
{
    [self updateLabelWithAngle:angle];
    self.scroller.contentOffset = [self angle2Offset:angle scrollView:self.scroller];
}

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setUpItem];
    }
    return self;
}

- (void)setUpItem
{
    [self addSubview:self.label];
    [self setUpScroller];
    [self addSubview:self.scroller];
    [self addSubview:self.indicator];
}

- (void)setUpScroller
{
    CGFloat left = CGRectGetWidth(self.bounds) / 2.;
    CGFloat width = 0;
    NSMutableArray *array = [NSMutableArray array];
    for (NSUInteger i = 0; i < 31; i ++) {
        UIView *view = [[UIView alloc] init];
        if (i % 5 == 0) {
            //大杠
            view.backgroundColor = [UIColor whiteColor];
            view.bounds = CGRectMake(0, 0, 3, 16);
            view.tag = 666;
        } else {
            //小杠
            view.backgroundColor = [UIColor lightGrayColor];
            view.bounds = CGRectMake(0, 0, 1.6, 8);
        }
        CGPoint center = CGPointMake(left + i * 16, self.scroller.bounds.size.height / 2);
        width = center.x;
        view.layer.cornerRadius = CGRectGetWidth(view.bounds)/2;
        view.center = center;
        [self.scroller addSubview:view];
    }
    self.keyDegreeBar = array;
    self.scroller.contentSize = CGSizeMake(width + self.scroller.bounds.size.width / 2, self.scroller.bounds.size.height);
    self.scroller.contentOffset = CGPointMake(self.scroller.contentSize.width/2, 0);
    _isFeedback = true;
}

//如果滚动的位置在这几个大杠附近，则需要自动校准
- (BOOL)matchRange:(CGFloat)percent outAngle:(CGFloat *)outAngle
{
    CGFloat angle = percent * 90 - 45;
    //设置校准范围为+-1
    CGFloat range = 1;
    // -45 , -30 , -15, 0, 15, 30, 45
    if (angle < (-45 + range) && angle > (-45 - range)) {
        *outAngle = -45;
        return true;
    }
    
    if (angle < (-30 + range) && angle > (- 30 - range)) {
        *outAngle = - 30;
        return true;
    }
    if (angle < (-15 + range) && angle > (- 15 - range)) {
        *outAngle = - 15;
        return true;
    }
    if (angle < (0 + range) && angle > (0 - range)) {
        *outAngle = 0;
        return true;
    }
    if (angle < (15 + range) && angle > (15 - range)) {
        *outAngle = 15;
        return true;
    }

    if (angle < (30 + range) && angle > (30 - range)) {
        *outAngle = 30;
        return true;
    }
    
    if (angle < (45 + range) && angle > (45 - range)) {
        *outAngle = 45;
        return true;
    }
    *outAngle = 0;
    return false;
}

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat offx = self.scroller.contentSize.width/2 - self.scroller.bounds.size.width/2;
    if (scrollView.contentOffset.x == offx) {
        self.indicator.backgroundColor = [UIColor whiteColor];
    } else {
        self.indicator.backgroundColor = [UIColor blueColor];
    }
    
    if (self.scroller.contentOffset.x == 0) {
        if (self.isFeedback == false && scrollView.isTracking) {
            self.isFeedback = true;
        }
        [self updateLabelWithAngle:[self offset2Angle:scrollView]];
        if (self.delegate && [self.delegate respondsToSelector:@selector(rotateScroller:percent:)]) {
            [self.delegate rotateScroller:self percent:0];
        }
    } else {
        CGFloat percent = self.scroller.contentOffset.x / (self.scroller.contentSize.width - self.scroller.bounds.size.width);
        CGFloat angle = 0;
        if ([self matchRange:percent outAngle:&angle]) {
            if (self.isFeedback == false && scrollView.isTracking) {
                self.isFeedback = true;
                CGFloat offsetX = (angle + 45) / 90 * (self.scroller.contentSize.width - self.scroller.bounds.size.width);
                scrollView.contentOffset = CGPointMake(offsetX, scrollView.contentOffset.y);
            }
        } else {
            self.isFeedback = false;
        }
        [self updateLabelWithAngle:[self offset2Angle:scrollView]];
        if (self.delegate && [self.delegate respondsToSelector:@selector(rotateScroller:percent:)]) {
            [self.delegate rotateScroller:self percent:percent];
        }
    }
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate) {
        CGFloat percent = self.scroller.contentOffset.x / (self.scroller.contentSize.width - self.scroller.bounds.size.width);
        CGFloat angle = 0;
        if ([self matchRange:percent outAngle:&angle]) {
            CGFloat offsetX = (angle + 45) / 90 * (self.scroller.contentSize.width - self.scroller.bounds.size.width);
            scrollView.contentOffset = CGPointMake(offsetX, scrollView.contentOffset.y);
            [self updateLabelWithAngle:[self offset2Angle:scrollView]];
            if (self.delegate && [self.delegate respondsToSelector:@selector(rotateScroller:percent:)]) {
                [self.delegate rotateScroller:self percent:percent];
            }
        }
    }
}

#pragma mark - private

- (CGPoint)angle2Offset:(CGFloat)angle scrollView:(UIScrollView *)scrollView
{
    if (angle > 45) {
        angle = 45;
    }
    
    if (angle < -45) {
        angle = -45;
    }
    CGFloat percent = (angle + 45) / 90;
    CGFloat x = (scrollView.contentSize.width - scrollView.bounds.size.width) * percent;
    return CGPointMake(x, 0);
}

- (NSInteger)offset2Angle:(UIScrollView *)scrollView
{
    if (scrollView.contentOffset.x == 0) {
        return -45;
    } else {
        CGFloat percent = scrollView.contentOffset.x / (scrollView.contentSize.width - scrollView.bounds.size.width);
        if (percent < 0) {
            percent = 0;
        } else if (percent > 1) {
            percent = 1;
        }
        
        NSInteger num = truncf(roundf(percent * 90 - 45));
        return num;
    }
}

- (void)updateLabelWithAngle:(CGFloat)angle
{
    self.label.text = [NSString stringWithFormat:@"旋转角度 %ld°", (long)angle];
    [self.label sizeToFit];
}

#pragma mark - setter

- (void)setIsFeedback:(BOOL)isFeedback
{
    _isFeedback = isFeedback;
    if (isFeedback) {
        UIImpactFeedbackGenerator *feedback = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
        [feedback impactOccurred];
    }
}

#pragma mark - lazy load

- (UILabel *)label
{
    if (!_label) {
        _label = [[UILabel alloc] initWithFrame:CGRectMake(0, 4, 100, 15)];
        _label.textColor = [UIColor whiteColor];
        _label.font = [UIFont systemFontOfSize:11];
    }
    return _label;
}

- (UIScrollView *)scroller
{
    if (!_scroller) {
        _scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 19, CGRectGetWidth(self.bounds), 37)];
        _scroller.delegate = self;
        _scroller.showsVerticalScrollIndicator = NO;
        _scroller.showsVerticalScrollIndicator = NO;
        _scroller.decelerationRate = UIScrollViewDecelerationRateFast;
    }
    return _scroller;
}

- (UIView *)indicator
{
    if (!_indicator) {
        _indicator = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 4, 22)];
        _indicator.center = self.scroller.center;
        _indicator.backgroundColor = [UIColor whiteColor];
    }
    return _indicator;
}

@end
